package com.qf.shiro;

import com.qf.pojo.DtsAdmin;
import com.qf.service.AdminService;
import com.qf.service.PermService;
import com.qf.service.RoleService;
import com.qf.util.bcrypt.BCryptPasswordEncoder;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Set;

/**
 * @author sunyamei
 * @version V1.0
 * @Project javase2203
 * @Package com.qf.shiro
 * @Description:
 * @Date 2022/7/25 19:52
 *
 * 自定义realm,当调用登录controller中的subject对象的login方法会触发这个类执行
 *
 *
 */
public class AdminAuthorizingRealm extends AuthorizingRealm {

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermService permService;

    /**
     * 授权方法,用户登录后赋予用户对应的角色,权限
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //1:获取用户对象
        DtsAdmin admin =(DtsAdmin) getAvailablePrincipal(principals);
        Integer[] roleIds = admin.getRoleIds();

        //2:根据用户ID,到数据库角色表中获取用户对应的角色集合
        Set<String> roleSet = roleService.queryRolesById(roleIds);

        //3:根据角色获取用户对应的权限集合
        Set<String> permSet = permService.queryPermByRoleIds(roleIds);

        //4:创建shiro框架要求的授权对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //5:将用户的角色和权限放入shiro框架的授权对象中
        info.setRoles(roleSet);
        info.setStringPermissions(permSet);

        //6:返回shiro的授权对象
        return  info;


    }

    /**
     * 认证方法(判断用户名密码是否正确)
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

      //1:获取用户输入发用户名,密码
        UsernamePasswordToken token1 =(UsernamePasswordToken)token;
        String username = token1.getUsername();
        String pwd = new String(token1.getPassword());

        //2:根据用户名到数据库中查询对应的用户对象
        List<DtsAdmin> adminList = adminService.findAdminByName(username);


        //3:判断用户查询到的用户对象是否正确
        if (adminList == null || adminList.size()==0){
            throw  new UnknownAccountException("找不到该用户,用户名有误");
        }
        //4:判断密码是否正确
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(pwd, adminList.get(0).getPassword())){
            throw new UnknownAccountException("密码不正确");
        }

        //5:封装shiro的用户对象返回给shiro框架处理
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(adminList.get(0), pwd, this.getName());
        return info;
    }
}
